/*
 * RamdomManager.h
 *
 *  Created on: 04/02/2013
 *      Author: vagner
 */

#ifndef RAMDOMMANAGER_H_
#define RAMDOMMANAGER_H_

#include <vector>
#include <sys/time.h>
#include <cstdlib>
#include <iostream>

namespace tp2cn {

class RamdomManager {
private:
	RamdomManager();

	//Verifica se a soma dos valores do vetor probabilidade é igual a 1
	static bool validaFuncaoProb(std::vector<float> vetorProb){

		float prob = 0.0;
		std::vector<float>::const_iterator itFloat;

		for(itFloat = vetorProb.begin(); itFloat != vetorProb.end(); itFloat++){
			prob += (*itFloat);
		}

		if(prob == 1.0){
			return true;
		}else{
			return false;
		}


	}

public:
	/*
	 * Escolhe aleatoriamente um inteiro entre min e max[inclusive], sendo que
	 * todos os valores tem igual probabilidade de sair.
	 */
	static int escolheIgualProb(int min, int max){

		int dif;
		timeval time;
		gettimeofday(&time,NULL);
		std::srand(time.tv_sec*time.tv_usec);
		int num_random;

		dif = max - min;
		//Escolhendo um inteiro entre 0 e dif + 1
		num_random = std::rand() % (dif + 1);

		//Tornando num_ramdom um valor entre min e max
		num_random+= min;

		return num_random;
	}

	/*
	 * Escolhe aleatoriamente um inteiro entre min e max, sendo que os
	 * valores a serem escolhidos possuem diferentes probabilidades. A probabilidade
	 * do i-esimo valor entre min e max está na i-esima posição do vector vetorProb.
	 * A soma dos valores contidos no vetorProb necessariamente deve resultar em 1.
	 */
	static int escolheDifProb(int min, int max, std::vector<long double>& vetorProb){

		int num_random;
		std::vector<int> numerosSorteio;
		int i, j,k;
		int qtdeValores = 0;
		int posicaoSorteio;
		int totalNumGerados = 0;


		if(vetorProb.size() != (max - min + 1) ){
			/* Se o número de valores de probabilidade
			 * for diferente da faixa de números a serem sorteados
			 * retorna um erro.
			 */
			num_random = -1;
		}else{
			k = min;
			for(i = 0; i < (int) vetorProb.size(); i++){
				qtdeValores = vetorProb.at(i) * 100;
				totalNumGerados += qtdeValores;
				for(j = 0; j < qtdeValores; j++){
					numerosSorteio.push_back(k);
				}
				k++;
			}

			std::cout << std::endl;
			posicaoSorteio = escolheIgualProb(0,totalNumGerados-1);
			num_random = numerosSorteio.at(posicaoSorteio);
		}
		return num_random;
	}

	/*Normaliza um valor entre [0,1] utilizando o método
	 * do máximo/minimo
	 */
	static long double normalizaValores(long double valor, long double max, long double min){
		long double novoValor;

		//std::cout <<"valor: " << valor<<  " max: " << max << " min: " << min << std::endl;
		if(valor == max && valor == min){
			novoValor = 1.0;

		}else if ( valor == min){
			novoValor = 0.0;
		}
		else{
			novoValor = (valor - min ) / (max - min);
		}
		if(novoValor < 0){
			novoValor = 0.0;
		}
		//std::cout << "Valor normalizado: " << novoValor << std::endl;

		std::cout.precision(2);
		return(novoValor);
	}



	virtual ~RamdomManager();
};

} /* namespace tp2cn */
#endif /* RAMDOMMANAGER_H_ */
